<?php
class FluxoSolicitacaoRelotacao
{
    const ERRO_AUTORIZACAO = 'Você não tem autorização suficiente para realizar esta operação neste momento.';
    
    public static function getAlertsStatus($pfcid)
    {
        $array = array();
        switch ($pfcid) {
            case PerfilComportamental::NucleoGestor:
                $array = array(Status::Permutacao_Solicitada);
                break;
            case PerfilComportamental::Empresa:
                $array = array(Status::Permutacao_Solicitada);
                break;
         }
         return $array;
    }
    
    /**
     * Solicitar a Permuta entre duas Solicitações de Relotação
     * @param $idSolicitacaoRelotacao1
     * @param $idSolicitacaoRelotacao2
     */
    public static function solicitarPermuta($idSolicitacaoRelotacao1, $idSolicitacaoRelotacao2)
    {
        self::isAuthorized('solicitarPermuta', $idSolicitacaoRelotacao1, $idSolicitacaoRelotacao2, TRUE);
        
        $solicitacaoRelotacao1 = new SolicitacaoRelotacao($idSolicitacaoRelotacao1);
        $solicitacaoRelotacao2 = new SolicitacaoRelotacao($idSolicitacaoRelotacao2);
        
        $candidatoVaga1 = new CandidatoVaga($solicitacaoRelotacao1->candidatovagaid);
        $candidatoVaga2 = new CandidatoVaga($solicitacaoRelotacao2->candidatovagaid);
        
        try {
            global $usuario;
            
    		pg_query(conexao::Conectar(), 'begin');
    		
        	// Movimentar A para B
        	$mcv = new MovimentacoesCandidatoVaga();
        	$mcv->candidatovagaidorigem  	= $candidatoVaga1->candidatovagaid;
        	$mcv->dataregistro				= date('d/m/Y H:i:s');
        	$mcv->operadorid				= $usuario->operadorid;
        	$mcv->vagadestino				= $candidatoVaga2->vagaid;
        	$mcv->salvar();
        	
        	// Movimentar B para A
        	$mcv = new MovimentacoesCandidatoVaga();
        	$mcv->candidatovagaidorigem  	= $candidatoVaga2->candidatovagaid;
        	$mcv->dataregistro				= date('d/m/Y H:i:s');
        	$mcv->operadorid				= $usuario->operadorid;
        	$mcv->vagadestino				= $candidatoVaga1->vagaid;
        	$mcv->salvar();
        	
        	// Inserir Status em A
        	$candidatoVaga1->inserirHistorico(Status::Permutacao_Solicitada);
        	
        	// Inserir Status em B
        	$candidatoVaga2->inserirHistorico(Status::Permutacao_Solicitada);
        	
        	pg_query(conexao::Conectar(), 'commit');
        	
        } catch ( exception $e ){
    		pg_query(conexao::Conectar(), 'rollback');
    		throw new Exception($e->getMessage());
    	}
    }
    
    /**
     * Finalizar a permuta entre dois funcionários
     * @param CandidatoVaga $candidatoVaga
     */
    public static function finalizarPermuta(CandidatoVaga $candidatoVaga)
    {
        self::isAuthorizedFinalizar($candidatoVaga, TRUE);
        
        try { 
    		pg_query(conexao::Conectar(), "begin");
    		
    		// Movimentacao
    		$movimentacao = $candidatoVaga->getMovitacoesCandidatoVagaOrigem();
    		
    		// Vaga Destino
    		$vagaDestino = new Vaga($movimentacao->vagadestino);
    		// CandidatoVaga Destino
    		$candidatoVagaDestino = $vagaDestino->getCandidatoVagaAtivo();
    		
    		// Operações da 1a Vaga ---------------------------------------------------------------
    		
    		// Desabilita a candidatovaga antiga
    		$candidatoVaga->ativo = FALSE;
    		$candidatoVaga->salvar();
    		
    		// Insere os Status na candidatovaga antiga
    		$candidatoVaga->inserirHistorico(Status::Permutacao_Confirmada);
    		
    		// Cria a nova Candidatovaga pra a vaga A
    		$candidatoVagaNovo = new CandidatoVaga();
    		$candidatoVagaNovo->candidatovagaid = NULL;
    		$candidatoVagaNovo->vagaid = $vagaDestino->vagaid;
    		$candidatoVagaNovo->candidatoid = $candidatoVaga->candidatoid;
    		$candidatoVagaNovo->adminissaosugestao = $candidatoVaga->adminissaosugestao;
    		$candidatoVagaNovo->admissao = date('d/m/Y');
    		$candidatoVagaNovo->registroterceirizada = $candidatoVaga->registroterceirizada;
    		$candidatoVagaNovo->ativo = TRUE;
    		$candidatoVagaNovo->salvar();
    		
    		// Insere o status na nova candidatovaga
    		$candidatoVagaNovo->inserirHistorico(Status::Candidato_Relotado);
    		$candidatoVagaNovo->inserirHistorico(Status::Candidato_Contratado, NULL, 1);
    		
    		// Registra a movimentação
    		$movimentacao->candidatovagaiddestino = $candidatoVagaNovo->candidatovagaid;
    		$movimentacao->salvar();
    		
    		$solicitacaoRelotacao = new SolicitacaoRelotacao();
    		$solicitacaoRelotacao = $solicitacaoRelotacao->RegistrarRelotacao($candidatoVaga->candidatovagaid, $candidatoVagaDestino->candidatovagaid);
    		
    		// Operações da 2a Vaga ---------------------------------------------------------------
    		
    		// Desabilita a candidatovaga antiga
    		$candidatoVagaDestino->ativo = FALSE;
    		$candidatoVagaDestino->salvar();
    		
    		// Insere os Status na candidatovaga antiga
    		$candidatoVagaDestino->inserirHistorico(Status::Permutacao_Confirmada);
    		
    		// Cria a nova Candidatovaga pra a vaga A
    		$candidatoVagaNovo2 = new CandidatoVaga();
    		$candidatoVagaNovo2->candidatovagaid = NULL;
    		$candidatoVagaNovo2->vagaid = $candidatoVaga->vagaid;
    		$candidatoVagaNovo2->candidatoid = $candidatoVagaDestino->candidatoid;
    		$candidatoVagaNovo2->adminissaosugestao = $candidatoVagaDestino->adminissaosugestao;
    		$candidatoVagaNovo2->admissao = date('d/m/Y');
    		$candidatoVagaNovo2->registroterceirizada = $candidatoVagaDestino->registroterceirizada;
    		$candidatoVagaNovo2->ativo = TRUE;
    		$candidatoVagaNovo2->salvar();
    		
    		// Insere o status na nova candidatovaga
    		$candidatoVagaNovo2->inserirHistorico(Status::Candidato_Relotado);
    		$candidatoVagaNovo2->inserirHistorico(Status::Candidato_Contratado, NULL, 1);
    		
    		// Registra a movimentação
    		$movimentacao = $candidatoVagaDestino->getMovitacoesCandidatoVagaOrigem();
    		$movimentacao->candidatovagaiddestino = $candidatoVagaNovo2->candidatovagaid;
    		$movimentacao->salvar();
    		
    		pg_query(conexao::Conectar(), "commit");
    		
    		return $candidatoVagaNovo;
    	} 
    	catch (exception $e){
    		pg_query(conexao::Conectar(), "rollback");
    		throw new Exception($e->getMessage());
    	}
    }
    
    /**
     * Verifica se o usuário tem acesso à determinada operação
     * @param $operacao
     * @param $throwExceptions
     */
    public static function isAuthorized($operacao, $idSolicitacaoRelotacao1, $idSolicitacaoRelotacao2, $throwExceptions = FALSE)
    {
        global $usuario, $pfcid;
        
        switch ($operacao) {
            case 'solicitarPermuta':
                
                if (!$usuario->isAuthorized(Operacao::MOVIMENTACAO_SOLICITARRELOTACAO)) {
                    if ($throwExceptions) {
                        throw new Exception('Você precisa da permissão 
                        	"Movimentação/Solicitar Relotação" para realizar esta operação');
                    }
                    return FALSE;
                }
                
                $view = new ViewSolicitacaoRelotacao();
    	
            	$criterio = array();
            	
            	// Solicitação 1
            	$criterio['precondicao'] = 'solicitacaorelotacaoid = ' . $idSolicitacaoRelotacao1;
            	$s1 = pg_fetch_object($view->listar($criterio));
            	
            	// Solicitação 2
            	$criterio['precondicao'] = 'solicitacaorelotacaoid = ' . $idSolicitacaoRelotacao2;
            	$s2 = pg_fetch_object($view->listar($criterio));
        
            	// Pré-condições
            	
            	// 1. Mesmo Cargo
            	if ($s1->cargoid != $s2->cargoid) {
            	    if ($throwExceptions) {
            		    throw new Exception('Cargos incompatíveis.');
            	    }
            	    return FALSE;
            	}
        
            	// 2. Mesmo Salário
            	if ($s1->salario != $s2->salario) {
            	    if ($throwExceptions) {
            		    throw new Exception('Salários incompatíveis.');
            	    }
            	    return FALSE;
            	}
        
            	// 3. Mesmo órgao
            	if ($s1->orgaoid != $s2->orgaoid) {
            	    if ($throwExceptions) {
            		    throw new Exception('Órgãos incompatíveis.');
            	    }
            	    return FALSE;
            	}
            	
            	// 4. Mesma empresa
            	if ($s1->empresaid != $s2->empresaid) {
            	    if ($throwExceptions) {
            		    throw new Exception('Empresas incompatíveis.');
            	    }
            	    return FALSE;
            	}
        
            	// 5. Lotacaoorigem bate com lotacadestino
            	if ($s1->lotacaoorigem  != $s2->lotacaodestino OR $s1->lotacaodestino != $s2->lotacaoorigem ) {
            	    if ($throwExceptions) {
            	        throw new Exception('Lotações incompatíveis.');
            	    }
            	    return FALSE;
            	}
        
            	$objeto1 = new SolicitacaoRelotacao($idSolicitacaoRelotacao1);
            	$objeto2 = new SolicitacaoRelotacao($idSolicitacaoRelotacao2);
            	
            	$candidatovaga1 = new CandidatoVaga($objeto1->candidatovagaid);
            	$candidatovaga2 = new CandidatoVaga($objeto2->candidatovagaid);
            	
            	$status1 = $candidatovaga1->getHistoricoAtual()->statusid;
            	$status2 = $candidatovaga2->getHistoricoAtual()->statusid;
            	
            	// Confirma os status dos candidatos envolvidos (deve ser contratação finalizada)
            	if ($status1 != Status::Candidato_ContratacaoFinalizada){
            		$candidato = new Candidato($candidatovaga1->candidatoid);
            		if ($throwExceptions) {
            		    throw new Exception('O candidato ' . $candidato->nome . ' não pode ser relotado.' . $status1);
            		}
            		return FALSE;
            	}
            	elseif ( $status2 != Status::Candidato_ContratacaoFinalizada ){
            		$candidato = new Candidato( $candidatovaga2->candidatoid );
            		if ($throwExceptions) {
            		    throw new Exception('O candidato ' . $candidato->nome . ' não pode ser relotado.' . $status2);
            		}
            		return FALSE;
            	}
            	
            	return TRUE;
                
                break;
        }
        if ($throwExceptions) {
            throw new Exception(self::ERRO_AUTORIZACAO);
        }
        return FALSE;
    }
    
    public static function isAuthorizedFinalizar(CandidatoVaga $candidatoVaga, $throwExceptions = FALSE)
    {
        $vaga     = $candidatoVaga->getVaga();
        $statusid = $candidatoVaga->getStatusAtual();
        $contrato = $vaga->getContrato();
        
        global $usuario, $pfcid;
        
        // Operação
        if (!$usuario->isAuthorized(Operacao::MOVIMENTACAO_PROMOCAO)) {
            if ($throwExceptions) {
                throw new Exception('Não é possível realizar esta operação, pois você precisa da operação Movimentação/Promoção.');
            }
            return FALSE;
        }
        
        if (!$contrato->podeMovimentarCandidatos()) {
            if ($throwExceptions) {
                throw new Exception('Não é possível realizar esta operação, pois o contrato não está confirmado.');
            }
            return FALSE;
        }
        
        if ($vaga->statusid != Status::Vaga_Ocupada) {
            if ($throwExceptions) {
                throw new Exception('Não é possível realizar esta operação, pois a vaga não está ocupada.');
            }
            return FALSE;
        }
        
        if (!$usuario->isVagaPermitida($vaga->vagaid)) {
            if ($throwExceptions) {
                throw new Exception('Não é possível realizar esta operação, pois você não tem acesso à esta vaga.');
            }
            return FALSE;
        }
        
        if ($pfcid == PerfilComportamental::Empresa 
        AND $statusid == Status::Permutacao_Solicitada) {
            return TRUE;
        }
        
        if ($throwExceptions) {
            throw new Exception(self::ERRO_AUTORIZACAO);
        }
        return FALSE;
    }
}